﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProjectEulerSolutions
{
    /*
     * 
     * The number 3797 has an interesting property. Being prime itself, it is possible to continuously remove digits from left to right, and remain prime at each stage: 3797, 797, 97, and 7. Similarly we can work from right to left: 3797, 379, 37, and 3.

Find the sum of the only eleven primes that are both truncatable from left to right and right to left.

NOTE: 2, 3, 5, and 7 are not considered to be truncatable primes.

     * 
     * */
    class Problem37
    {
        public static string Calculate()
        {
            int[] startingDigits = new int[] { 2, 3, 5, 7 };
            int[] middleDigits = new int[] { 1, 3, 7, 9 };
            int[] endDigits = new int[] { 3, 7 };

            List<long> truncatablePrimes = new List<long>();

            truncatablePrimes.AddRange(GetTruncatablePrimes(2));
            truncatablePrimes.AddRange(GetTruncatablePrimes(3));
            truncatablePrimes.AddRange(GetTruncatablePrimes(5));
            truncatablePrimes.AddRange(GetTruncatablePrimes(7));

            foreach (long l in truncatablePrimes)
                Console.WriteLine(l);

            return truncatablePrimes.Sum().ToString();
        }

        public static List<long> GetTruncatablePrimes(long startingPrime)
        {
            List<long> truncatablePrimes = new List<long>();

            long add1 = startingPrime * 10 + 1;
            if (CommonFunctions.IsPrime(add1))
                truncatablePrimes.AddRange(GetTruncatablePrimes(add1));

            long add3 = startingPrime * 10 + 3;
            if (CommonFunctions.IsPrime(add3))
            {
                truncatablePrimes.AddRange(GetTruncatablePrimes(add3));

                int numDigits = (int)Math.Ceiling(Math.Log10(add3));
                bool isTruncatablePrime = true;
                for (int i = numDigits - 1; i > 1; i--)
                {
                    if (!CommonFunctions.IsPrime(add3 % (long)Math.Pow(10, i)))
                    {
                        isTruncatablePrime = false;
                        break;
                    }
                }

                if (isTruncatablePrime)
                    truncatablePrimes.Add(add3);
            }

            long add7 = startingPrime * 10 + 7;
            if (CommonFunctions.IsPrime(add7))
            {
                truncatablePrimes.AddRange(GetTruncatablePrimes(add7));

                int numDigits = (int)Math.Ceiling(Math.Log10(add7));
                bool isTruncatablePrime = true;
                for (int i = numDigits - 1; i > 1; i--)
                {
                    if (!CommonFunctions.IsPrime(add7 % (long)Math.Pow(10, i)))
                    {
                        isTruncatablePrime = false;
                        break;
                    }
                }

                if (isTruncatablePrime)
                    truncatablePrimes.Add(add7);
            }

            long add9 = startingPrime * 10 + 9;
            if (CommonFunctions.IsPrime(add9))
                truncatablePrimes.AddRange(GetTruncatablePrimes(add9));

            return truncatablePrimes;
        }
    }
}
